import re
import logging

"""
核电工程编码的规范
"""


def identify_text(text: str):
    # 厂房的识别,2到3位
    factory_pattern = re.compile(r"^([0-9])([DKLMNRW])([A-Z]?)$")
    # # 三字码的识别
    # room_pattern = re.compile(r'^[A-Za-z]{2,3}$')
    # 厂房及房间的识别
    factory_room_pattern = re.compile(
        r"^([0-9])([A-Z])([A-Z]?)([0-9])([0-9]{2})$"
    )
    # 汽轮机厂房之特例
    special_factory_pattern = re.compile(
        r"^([0-9])([A-Z]{1})([0-9])([0-9])([A-Z])$"
    )
    # 设备识别
    # equipment_pattern = re.compile(r'^([0-9]?)([A-Z]{3})([0-9]{3})([A-UW-Z][A-Z])$')
    equipment_pattern = re.compile(
        r"^([A-Z]?)([0-9]?)([A-Z]{3})?([0-9]{3})([A-UW-Z][A-Z])$"
    )
    # 阀门识别
    # valve_pattern = re.compile(r'^([0-9]?)([A-Z]{3})([0-9]{3})(V)([A-Z])$')
    valve_pattern = re.compile(
        r"^([A-Z]?)([0-9]?)([A-Z]{3})?([0-9]{3})(V)([A-Z])$"
    )
    # 工程图纸的识别符号
    drawing_symbol_pattern = re.compile(
        r"^([A-Z]{2})([0-9]?)([0-9A-Z]{5})([0-9A-Z]{3})([A-Z][0-9A-Z]{3})([0-9]{2})([A-Z]{2})([0-9]{3})$"
    )
    # 电缆的识别符号
    cable_pattern = re.compile(
        r"^([A-Z]?)([0-9]?)([A-Z]{3})([A-Z])([0-9]{3})$"
    )
    # 判断文本是否符合规则，并输出结果
    results = {
        "厂房识别": factory_pattern.match(text) is not None,
        # "三字码识别": room_pattern.match(text) is not None  and  text in frstext.keys() ,
        "厂房及房间识别": factory_room_pattern.match(text) is not None,
        "汽轮机厂房识别": special_factory_pattern.match(text) is not None,
        "设备识别": equipment_pattern.match(text) is not None,
        "阀门识别": valve_pattern.match(text) is not None,
        "工程图纸识别": drawing_symbol_pattern.match(text) is not None,
        "电缆识别": cable_pattern.match(text) is not None,
    }

    if list(results.values()).count(True) > 1:
        logging.error(f"错误!! {text}")
        return
    output_dict = ""
    for key, value1 in results.items():
        if value1:
            if key == "厂房识别":
                output_dict = text
            if key == "三字码识别":
                output_dict = text
            if key == "厂房及房间识别":
                output_dict = text
            if key == "汽轮机厂房识别":
                output_dict = text
            if key == "设备识别":
                # value = equipment_pattern.match(text)
                output_dict = text
            if key == "阀门识别":
                # value = valve_pattern.match(text)
                output_dict = text
            if key == "工程图纸识别":
                # value = drawing_symbol_pattern.match(text)
                output_dict = text
            if key == "电缆识别":
                # value = cable_pattern.match(text)
                output_dict = text
    return output_dict


# identify_text(chunk_1)

"""
国标识别
text：文本
codelines：编码文件
"""


def extract_alphanumeric(text: str, codelines: list):
    text = str(text)
    text = text.replace("\begin{table}", "")
    text = text.replace("\toprule", "")
    text = text.replace("oprule", "")
    text = text.replace("\bottomrule", "")
    text = text.replace("\midrule", "")
    text = text.replace("midrule", "")
    text = text.replace("bottomrule", "")

    # text =  text.replace("\t", "").replace("\n", "")
    text = text.upper().replace("\t", "").replace("\n", "")

    # 国标的匹配

    # 如果是这个结尾怎么办，就是这个编号结尾
    text = text + "\n"
    atemp = re.compile(
        r"((?:GB\/?Z?T?J?|GJB|JGJ?|NB\/?T?|HAD|HAF|HG|CECS|CJ\/?J?T?).*?)(?=[\u4e00-\u9fa5A-Za-z《、,，。\n♦])"
    )
    amatches: list = atemp.findall(text)
    amatchess: list = []
    text = text.replace("\n", "")
    for aamatch in amatches:
        if len(aamatch) == 2 or len(aamatch) == 3:
            continue
        # aamatch = amatches[0]
        aamatch = aamatch.replace(" ", "")
        aamatch = aamatch.replace("(", "（")
        aamatch = aamatch.replace(")", "）")
        open_brackets = []
        close_brackets = []
        # 计算左括号和右括号的数量
        for chari, char in enumerate(aamatch):
            if char == "（":
                open_brackets.append(chari)
            elif char == "）":
                close_brackets.append(chari)
        if len(open_brackets) != len(close_brackets):
            if len(close_brackets) > len(open_brackets):
                aamatch = aamatch[: close_brackets[-1]]
        else:
            if len(close_brackets) != 0:
                if close_brackets[-1] < open_brackets[-1]:
                    aamatch = aamatch[: close_brackets[-1]]
        amatchess.append(aamatch)
    for aamatch in amatches:
        text = text.replace(aamatch, "")

    # 找到除国标外的其他字符
    alphanumeric_pattern = re.compile(r"[0-9A-Za-z%/^\-^\.^\{^\}^\]]{2,}")
    matches: list = alphanumeric_pattern.findall(text)
    matches = list(set(matches))
    errorlist: list = []
    results: list = []
    for part in matches:
        # 如果是带百分号，1.5这种double类型，或者是1.这种标签格式，以及mm，cm这种单位直接给去除
        ttemp_biao = False
        if part.isdigit() or "%" in part:
            continue
        if re.match(r"(^\d+(\.\d+)?(MM|CM|M)$)", part):
            continue
        if re.match(r"\d+\.\d+", part):
            continue
        if re.match(r"\d+\.", part):
            continue
        # 对于45/46这种
        number_part = part.replace("/", "")
        if number_part.isdigit():
            continue

        # 先直接匹配是否存在给的黑话术语里面
        for codeline in codelines:
            if codeline.strip() == part:
                amatchess.append(part)
                ttemp_biao = True
                break
        if ttemp_biao:
            continue

        # 如果不存在，/是为了防止两个编码在一起比如 EPN003/002,这种要识别除003和002是两个编号
        # 或者是存在多个切分，就是EPN002/003/992MP,需要变成EPN002MP,EPN003MP,EPM992MP

        line = part.split("/")

        try:
            if len(line) != 1:
                if len(line) == 2 or (
                    (len(line) > 2)
                    and (all(len(part) == len(line[1]) for part in line[2:]))
                ):
                    commonpartlen = len(line[0]) - len(line[1])
                    commonpart = line[0][:commonpartlen]
                    for i, linee in enumerate(line):
                        if not linee:
                            continue
                        if i == 0:
                            results.append(linee)
                        else:
                            results.append(commonpart + linee)
                elif len(line) > 2 and not all(
                    len(part) == len(line[1]) for part in line[2:]
                ):
                    lenhouzhui = len(line[-1]) - len(line[-2])
                    lenqianzhui = len(line[0]) - len(line[1])
                    houzhui = line[-1][lenhouzhui:]
                    qianzhui = line[0][:lenqianzhui]
                    for i, linee in enumerate(line):
                        if i == 0:
                            results.append(linee + houzhui)
                        elif i != len(line) - 1:
                            results.append(qianzhui + linee + houzhui)
                        elif i == len(line) - 1:
                            results.append(qianzhui + linee)
            else:
                # 需要去掉连接符
                part = part.replace("-", "")
                # if not part.isdigit():
                results.append(part)
        except Exception:
            errorlist.append(text)
            logging.error("错误，斜杠后的字符长度不一样")
    results = list(set(results))
    # amatchess是国标
    # results是返回的一些编码
    # matches：是匹配的一些编码，但这些需要过滤

    # results_s是去除纯字符的结果，之后再进行编码的匹配
    results_s: list = []
    for rrr in results:
        if not rrr.isdigit():
            for codeline in codelines:
                if codeline.strip() == rrr:
                    amatchess.append(rrr)
                    break
            results_s.append(rrr)

    results_complete_rule: list = []
    results_no_rule: list = []
    stand_rule = amatchess
    # 此时进行编码的匹配
    for rrr in results_s:
        results1 = identify_text(rrr)
        if results1:
            results_complete_rule.append(rrr)
        else:
            if "{" in rrr:
                continue
            if len(rrr) < 3:
                continue
            if (
                rrr == ".DOCX"
                or rrr == ".HTML"
                or rrr == ".XLSX"
                or rrr == ".PPTX"
                or rrr == ".IMAGE"
                or rrr == "BEGIN"
            ):
                continue
            if (
                rrr == "DOCX"
                or rrr == "HTML"
                or rrr == "XLSX"
                or rrr == "PPTX"
                or rrr == "IMAGE"
            ):
                continue
            results_no_rule.append(rrr)

    # results_complete_rule 完全符合设备编码规则的
    # results_no_rule 不符合字典的编码，不符合国标，不符合设备编码规则，但可能是因为我们的黑话库不全的原因
    # stand_rule 国标等库里面的内容
    # errorlist 进行切分会有问题的，例如 epc002/034/993mp 这种就可以切分，但有些切分不能匹配

    allright_code = results_complete_rule + stand_rule
    maybe_code = results_no_rule
    return allright_code, maybe_code
    # return results_complete_rule,results_no_rule,stand_rule,errorlist


# 进行黑话术语的补充
def Extracting_slang(chunk: str, slang_file: str, min_length: int):
    slang_list: list = []
    with open(slang_file, "r", encoding="utf-8") as f:
        h = f.readlines()
        for line in h:
            if len(line) > min_length:
                slang_list.append(line.replace("\n", ""))
    # 用来收集文本块中出现的黑话
    found_slang: list = []
    # 遍历每一个黑话项
    for slang in slang_list:
        # 检查黑话是否存在于文本块中
        if slang in chunk:
            # 如果存在，添加到收集器中
            found_slang.append(slang)
    return found_slang


def find_all_slang(chunk: str, slang_file, all_Slang_file, min_length):
    with open(all_Slang_file, "r", encoding="utf-8") as frs:
        codelines = frs.readlines()

    # allright_code:符合国标、设备规则、术语编码表
    # maybe_code:不符合以上的规则，但可能因为术语库覆盖不全面，例如D1STR-002-RG

    allright_code, maybe_code = extract_alphanumeric(chunk, codelines)

    # 术语编码
    result_code = allright_code + maybe_code
    # 术语
    slang = Extracting_slang(chunk, slang_file, min_length)
    unique_results = result_code + slang

    return unique_results


# find_all_slang(chunk,slang_file,all_Slang_file,min_length)


# chunk_1 = '''2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\31.png 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\32.png ♦ 全包裹式明铺(1): 1. 在设置混凝土全包裹前，需先对管道焊接处进行除 锈刷漆； 2. 混凝土包裹设置需进行基础硬化，基础与混凝土支 墩底部距离2 150mm ； 3. 示意图： 混凝土支墩全包裹 // ///////////////// / / / ////"〃 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\33.png 混凝土支墩基础 ♦全包裹式地埋铺设(2 )： 1. 在设置混凝土全包裹前，需先对管道焊接处进行除 锈刷漆； 2. 混凝土包裹设置需进行基础硬化，基础与混凝土支 墩底部距离2 150mm ； 3. 回填土的压实系数不应小于90%。回填土不得有坚硬 凸出物，回填时，混凝土支墩周围200mm以内的回填 土不得含有粒径大于10mm的坚硬石(砖)块； 4. 示意图： \\begin{table}[t]\n\\begin{tabular}{ll}\n\\toprule\n\\midrule\n文件编码：\n012-AB-B-2022-T03\n-OPC-00016 & 2023年-2024年核电厂厂内外生活水管道更换框架项 目 \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n 3.5辅助建筑 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\35.png ♦阀门井砖砌： 1. 为保证供水管道正常工作， 便于检修与操作管理，\n施工过程中如涉及到阀门 井制作， 尺寸要求： e 1800mm圆形立式砖砌阀门井，井深2000mm； 2. 设置一个e 200mm圆形立式集水槽，深度为200mm； 3. 管沟盖板采用混凝土钢筋制作， 铺设平整。 ♦挡墙制作： 1. 管道沿线环境若存在塌方隐患，对管道造成杂物堆 积、破坏等影响区域需视情况而定，增加混凝土支 墩或边坡挡墙对管道形成保护； ♦路面施工： 1. 混凝土路面：下铺2100mm碎石，上做260mm厚C25 混凝土路面，面层拉毛； 2. 彩砖地面：下铺2 100mm碎石，3 : 7灰土夯实，上铺 彩砖，水泥勾缝； 3. 具体施工参照实际现场对比规格执行。 3.6规范 本工程施工及管理的规范和标准包括但不限于： 1. 《城市给水工程规划规范》(GB 5282-98) 2. 《室外给水设计规范》(GBJ 13-86) (1997版) 3. 《给水排水管道工程施工及验收规范》(GB 50268-97) 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\36.png \\begin{table}[t]\n\\begin{tabular}{ll}\n\\toprule\n\\midrule\n文件编码：\n012-AB-B-2022-T03\n-OPC-00016 & 2023年-2024年核电厂厂内外生活水管道更换框架项 目 \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n 13/20 ♦ 《给水排水工程构筑物设计规范》(GB 50069-2002) 4. 《给水排水工程管道结构设计规范》(GB 50332-2002) 5. 《给排水管道工程施工及验收规范》(GB50268-97 ) 6. 《钢材在涂装油漆及相关漆料前预处理》-表面清洁度的 目测评定(£08501-1,1998) 7. 《工业设备管道防腐工程及验收规范》(HG229-91 ) ♦ 《城镇道路工程施工及质量验收规范》(CJJ1-2008) ♦ 《室外硬聚氯乙烯给水管道工程施工及验收规程》 (CECS 18-90) 8. 《城市供水水质标准》(CJ/T2006-2005) 9. 《给排水管道工程施工及验收规范》(GB50268-97 ) 3.7工程技术要求 ♦ 一般规定 1. 本技术规范书所述内容均作为乙方的施工依据； 2. 施工所需特殊设备及材料必须经甲方该项目主管技 术人员同意； 3. 主要管材、设备以及水泥、钢筋、油漆等重要材料 均需有厂家证明，同时须征得甲方同意后方可使用； 4. 乙方提供的主要管材、设备等货物必须是全新(包 含零部件)的产品设备，并必须符合国家检测标准 和该产品的出厂标准； 5. 乙方对提供的主要管材、设备等货物提供一年的免 费维修保修期，保修期内非因适用方的认为因素出 现质量问题，由甲方负责包修、包换并承担所涉及 到的所有费用。 ♦安装规定 a) 凡属隐蔽工程(包括管道回填、钢筋、回填、验槽 工程等)，未经甲方许可，乙方不得自行覆盖隐蔽并'''
# （GEX001AP、 GEX001TR-003TR）进行检查，不满 足程序《重要敏感区域管理》的要求。
# chunk = "PTR001BA 向传输池的补水路径 四因子公式"

# chunk_T = """
# 这是一个包含国家标准编号的文本：GB12345，还有GJB6789。(GB 5282-98)
# PTR001BA 向传输池的补水路径 四因子公式
# （GEX001AP、 GEX001TR-003TR）进行检查，不满 足程序《重要敏感区域管理》的要求。
# 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\31.png 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\32.png ♦ 全包裹式明铺(1): 1. 在设置混凝土全包裹前，需先对管道焊接处进行除 锈刷漆； 2. 混凝土包裹设置需进行基础硬化，基础与混凝土支 墩底部距离2 150mm ； 3. 示意图： 混凝土支墩全包裹 // ///////////////// / / / ////"〃 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\33.png 混凝土支墩基础 ♦全包裹式地埋铺设(2 )： 1. 在设置混凝土全包裹前，需先对管道焊接处进行除 锈刷漆； 2. 混凝土包裹设置需进行基础硬化，基础与混凝土支 墩底部距离2 150mm ； 3. 回填土的压实系数不应小于90%。回填土不得有坚硬 凸出物，回填时，混凝土支墩周围200mm以内的回填 土不得含有粒径大于10mm的坚硬石(砖)块； 4. 示意图： \\begin{table}[t]\n\\begin{tabular}{ll}\n\\toprule\n\\midrule\n文件编码：\n012-AB-B-2022-T03\n-OPC-00016 & 2023年-2024年核电厂厂内外生活水管道更换框架项 目 \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n 3.5辅助建筑 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\35.png ♦阀门井砖砌： 1. 为保证供水管道正常工作， 便于检修与操作管理，\n施工过程中如涉及到阀门 井制作， 尺寸要求： e 1800mm圆形立式砖砌阀门井，井深2000mm； 2. 设置一个e 200mm圆形立式集水槽，深度为200mm； 3. 管沟盖板采用混凝土钢筋制作， 铺设平整。 ♦挡墙制作： 1. 管道沿线环境若存在塌方隐患，对管道造成杂物堆 积、破坏等影响区域需视情况而定，增加混凝土支 墩或边坡挡墙对管道形成保护； ♦路面施工： 1. 混凝土路面：下铺2100mm碎石，上做260mm厚C25 混凝土路面，面层拉毛； 2. 彩砖地面：下铺2 100mm碎石，3 : 7灰土夯实，上铺 彩砖，水泥勾缝； 3. 具体施工参照实际现场对比规格执行。 3.6规范 本工程施工及管理的规范和标准包括但不限于： 1. 《城市给水工程规划规范》(GB 5282-98) 2. 《室外给水设计规范》(GBJ 13-86) (1997版) 3. 《给水排水管道工程施工及验收规范》(GB 50268-97) 2023年-2024年核电厂厂内外生活水管道更换框架项目.docx\\image\\36.png \\begin{table}[t]\n\\begin{tabular}{ll}\n\\toprule\n\\midrule\n文件编码：\n012-AB-B-2022-T03\n-OPC-00016 & 2023年-2024年核电厂厂内外生活水管道更换框架项 目 \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n 13/20 ♦ 《给水排水工程构筑物设计规范》(GB 50069-2002) 4. 《给水排水工程管道结构设计规范》(GB 50332-2002) 5. 《给排水管道工程施工及验收规范》(GB50268-97 ) 6. 《钢材在涂装油漆及相关漆料前预处理》-表面清洁度的 目测评定(£08501-1,1998) 7. 《工业设备管道防腐工程及验收规范》(HG229-91 ) ♦ 《城镇道路工程施工及质量验收规范》(CJJ1-2008) ♦ 《室外硬聚氯乙烯给水管道工程施工及验收规程》 (CECS 18-90) 8. 《城市供水水质标准》(CJ/T2006-2005) 9. 《给排水管道工程施工及验收规范》(GB50268-97 ) 3.7工程技术要求 ♦ 一般规定 1. 本技术规范书所述内容均作为乙方的施工依据； 2. 施工所需特殊设备及材料必须经甲方该项目主管技 术人员同意； 3. 主要管材、设备以及水泥、钢筋、油漆等重要材料 均需有厂家证明，同时须征得甲方同意后方可使用； 4. 乙方提供的主要管材、设备等货物必须是全新(包 含零部件)的产品设备，并必须符合国家检测标准 和该产品的出厂标准； 5. 乙方对提供的主要管材、设备等货物提供一年的免 费维修保修期，保修期内非因适用方的认为因素出 现质量问题，由甲方负责包修、包换并承担所涉及 到的所有费用。 ♦安装规定 a) 凡属隐蔽工程(包括管道回填、钢筋、回填、验槽 工程等)，未经甲方许可，乙方不得自行覆盖隐蔽并
# \begin{table}[t]
# \begin{tabular}{llllllll}
# \toprule
# \midrule
# 核电厂 & QSR & 硼加热系统（BNI部分） &  &  &  & D1 执行 44/45 &  \\
# 核电厂 & QSR & 硼加热系统（BNI部分） &  &  &  & N-OP-S-3-RRB-002 &  \\
# &附录 &  &  &  &  &  &  &  \\
# 附录3：电加热回路的识别（1/2） &  &  &  &  &  &  &  \\
# 直流流程 & 从 &  & 到 & BNI回路 & 电源 &  &  \\
# 直流流程 & 从 &  & 到 & BNI回路 & 正常 &  & 备用 \\
# RRB301TY & PTR016VB &  & PTR001BA & PTR001BA 充水 & RRB301AR &  & RRB401AR \\
# RRB302TY & RRB310TY &  & RRB311TY & PTR001BA仪表排水 & RRB301AR &  & RRB401AR \\
# RRB303TY & PTR001BA &  & PTR164LG & PTR001BA 取样 & RRB301AR &  & RRB401AR \\
# RRB304TY & PTR001BA &  & EAS002VB & EAS002PO 供水 & RRB301AR &  & RRB401AR \\
# RRB305TY & PTR001BA &  & EAS001VB & EAS001PO 供水 & RRB301AR &  & RRB401AR \\
# RRB306TY & EAS003KD &  & PTR001BA & EAS试验回流管路 & RRB301AR &  & RRB401AR \\
# RRB313TY & RRB315TY &  & RPE373VP & 006CU向TEU排水 & RRB301AR &  & RRB401AR \\
# RRB315TY & RPE028PO &  & RPE213VE & 006CU向TER排水 & RRB301AR &  & RRB401AR \\
# RRB307TY & PTR001BA &  & 管道
# PTR100 & RRA/PTR备用管路 & RRB302AR &  & RRB402AR \\
# RRB309TY & PTR001BA &  & RPE006CU & PTR001BA 排水 & RRB302AR &  & RRB402AR \\
# RRB310TY & PTR001BA &  & RRB302TY & PTR018MN & RRB302AR &  & RRB402AR \\
# RRB311TY & PTR001BA &  & RPE006CU & PTR003SN & RRB302AR &  & RRB402AR \\
# RRB312TY & PTR001BA &  & RRB302TY & PTR020MN & RRB302AR &  & RRB402AR \\
# RRB314TY & PTR019VB &  & PTR016VB & PTR001BA 充水 & RRB302AR &  & RRB402AR \\
# RRB320TY & PTR001BA &  & RRB302TY & PTR019MN & RRB302AR &  & RRB402AR \\
# RRB321TY & PTR001BA &  & RRB302TY & PTR011LN & RRB302AR &  & RRB402AR \\
# RRB322TY & PTR001BA &  & RRB302TY & PTR021MN & RRB302AR &  & RRB402AR \\
# 8RRB521TY & TEP031VP &  & TEP002BA & TEP002BA 充水 & 8RRB501AR &  &  \\
# 8RRB522TY & RRB521TY &  & TEP004BA & TEP004BA 充水 & 8RRB501AR &  &  \\
# 8RRB523TY & RRB521TY &  & TEP003BA & TEP003BA 充水 & 8RRB501AR &  &  \\
# 8RRB524TY & TEP109VD &  & RRB521TY & TEP中间贮存罐充水 & 8RRB501AR &  &  \\
# 8RRB525TY & RRB524TY &  & TEP616VB & 蒸馏释放管路 & 8RRB501AR &  &  \\
# 8RRB705TY & RRB724TY &  & TES001BA & TEP向TES的释放管
# 路 & 8RRB7"""

# slang_file = r"/home/cdhappy/01Pdfstruct/heihauceshi_haoran/黑话/term_chinese.txt"
# all_Slang_file = r'/home/cdhappy/01Pdfstruct/heihauceshi_haoran/黑话/term_code.txt'
# # slang_file = r"./term_chinese.txt"
# # all_Slang_file = r'./term_code.txt'

# print(find_all_slang(chunk=chunk_T,slang_file=slang_file,all_Slang_file=all_Slang_file, min_length=4))
